package com.rdgzs.framework.utilsTools;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;

public class FileUploadUtils {
	private static final int BUFFER_SIZE = 32 * 1024;
	private static final String IMG_REGX = "\\.[bmp|gif|gepg|png]$";
	private String basePath = "";// 相对路径的基准路径 例 D:\test
	private String excludeFormatRegx = null;// 要排除的文件格式

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：文件上传
	 * @传入参数：
	 * @param fileName 文件名
	 * @param regx 正则表达式
	 */
	public static Boolean fileTypeVld(final String fileName, final String regx) throws IOException {
		Boolean flag = false;
		Pattern pattern = Pattern.compile(regx);
		Matcher matcher = pattern.matcher(fileName);
		if (matcher.find()) {
			flag = true;
		} else {
			flag = false;
		}
		return flag;
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：文件上传
	 * @传入参数：
	 * @param file
	 * @param filePath
	 * @param fileName
	 * @throws Exception
	 * @throws BaseCheckedException
	 */
	public String uploadFile(File file, String filePath, String fileName) throws Exception {
		boolean isExecute=true;
		this.initWebBasePath(filePath);
		String realPath = basePath + File.separator + fileName;

		if(StringUtils.isNotBlank(excludeFormatRegx)){
			if(fileTypeVld(fileName,excludeFormatRegx)){
				isExecute=false;
				throw new Exception("文件格式不正确！！！");
			}
		}
		if(isExecute){
			createDir(basePath);
			File dstFile=FileUploadUtils.createFile(realPath);//目标文件
			copyFile(file,dstFile);
		}
		
		return realPath;
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：文件对拷
	 * @传入参数：
	 * @param src 源文件
	 * @param dst 目标文件
	 */
	private void copyFile(File src, File dst) throws IOException {
		InputStream in = null;
		OutputStream out = null;
		try {
			in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
			out = new BufferedOutputStream(new FileOutputStream(dst), BUFFER_SIZE);
			byte[] buffer = new byte[BUFFER_SIZE];
			while (in.read(buffer) > 0) {
				out.write(buffer);
			}
			out.flush();
		} finally {
			if (null != in) {
				in.close();
			}
			if (null != out) {
				out.close();
			}
		}
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：根据 相对路径 计算 真实路径 [基于struts2]
	 * @传入参数：
	 * @param filePath 相对路径
	 */
	public String initWebBasePath(final String filePath) {
		if(StringUtils.isNotBlank(filePath)){
			this.basePath = ServletActionContext.getServletContext().getRealPath(filePath);
		}
		return this.basePath;
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：得到新的文件名 如果fileName为空则用新的文件名 如果fileName为null\空则用时间戳+随机码
	 * @传入参数：
	 * @param fileUploadFileName 上传时的原文件名
	 * @param fileName 指定新的文件名
	 */
	public static String getNewFileName(final String fileUploadFileName, final String fileName) throws Exception {
		try {
			String extName = ""; // 保存文件拓展名
			String newFileName = ""; // 保存新的文件名
			String nowTimeStr = ""; // 保存当前时间
			SimpleDateFormat sDateFormat;
			Random r = new Random();
			int rannum = (int) (r.nextDouble() * 89999) + 10000; // 获取随机数
			sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); // 时间格式化的格式
			nowTimeStr = sDateFormat.format(new Date()); // 当前时间
			extName = getExtension(fileUploadFileName);
			if (null == fileName || fileName.equals("")) {
				newFileName = nowTimeStr + rannum + "." + extName; // 文件重命名后的名字
			} else {
				newFileName = fileName + extName; // 文件重命名后的名字
			}
			return newFileName;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：删除指定文件下的多个文件
	 * @传入参数：
	 * @param fileList 文件名列表
	 * @param relativePath 文件相对路径
	 */
	public static void deleteFiles(final List<String> fileList, final String relativePath) {
		for (int index = 0; index < fileList.size(); index++) {
			String fullName = relativePath + fileList.get(index);
			deleteFile(fullName);
		}
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：在应用服务器通过相对地址删除文件
	 * @传入参数：
	 * @param relativeFullName 相对文件地址
	 */
	public static void deleteFileByRelativePath(final String relativeFullName) {
		String realPath = ServletActionContext.getServletContext().getRealPath(relativeFullName);
		deleteFile(realPath);
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：删除指定路径的文件
	 * @传入参数：
	 * @param fileFullName 文件绝对地址
	 */
	public static void deleteFile(final String fileFullName) {
		File file = new File(fileFullName);
		if (file.isFile() && file.exists()) {
			file.delete();
		}
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：创建目录
	 * @传入参数：
	 */
	public static void createDir(final String absolutePath) {
		File file = new File(absolutePath);
		// 如果该文件目录不存在，则创建一个新的目录
		if (!file.exists()) {
			file.mkdir();
		}
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：创建文件
	 * @传入参数：
	 * @throws IOException
	 */
	public static File createFile(final String uploadPath) throws IOException {
		File file = new File(uploadPath);
		if (!file.exists()) {
			file.createNewFile();
		}
		return file;
	}

	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：取出对应文件名的扩展名
	 * @传入参数：
	 * @throws IOException
	 */
	public static String getExtension(final String fileName) throws IOException {
		String extension = "";
		if (fileName != null && !fileName.equals("")) {
			if (fileName.lastIndexOf(".") != -1) {
				extension = fileName.substring(fileName.lastIndexOf(".") + 1);
			}
		}
		return extension;
	}
	
	/**
	 * @创建日期：2013-5-26
	 * @开发人员：李广彬
	 * @功能描述：
	 * @传入参数：
	 * @throws IOException
	 */
	public static boolean hasExtension(final String fileName) throws IOException {
		return fileName.contains(".");
	}

	public String getBasePath() {
		return basePath;
	}

	public void setBasePath(String basePath) {
		this.basePath = basePath;
	}

	public String getExcludeFormatRegx() {
		return excludeFormatRegx;
	}

	public void setExcludeFormatRegx(String excludeFormatRegx) {
		this.excludeFormatRegx = excludeFormatRegx;
	}

}
